package com.youka.bussiness.aspect;

import com.youka.bussiness.common.base.BaseEntity;
import com.youka.bussiness.common.base.BaseException;
import com.youka.bussiness.common.base.Const;
import com.youka.bussiness.common.bean.RestResp;
import com.youka.bussiness.common.utils.DateUtil;
import com.youka.bussiness.common.utils.JsonUtil;
import com.youka.bussiness.common.utils.RedisUtil;
import com.youka.bussiness.common.utils.SpringContextUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

/**
 * 环绕切面
 */
@Slf4j
@Aspect
@Component
public class ServiceAspect {


    /**
     * 切点
     */
    @Pointcut("execution(* com.youka.bussiness.controller.*.*Controller.*(..))")
    public void aspect() {
    }

    @Autowired
    private RedisUtil redisUtil;

//    @Resource
//    private SysLogMapper sysLogMapper;
//
//    @Resource
//    private UserInfoMapper userInfoMapper;
//
//    @Resource
//    private SysAdminMapper sysAdminMapper;

    /**
     * 切面执行方法
     *
     * @param proceedingJoinPoint
     * @return
     */
    @Around("aspect()")
    public Object advice(ProceedingJoinPoint proceedingJoinPoint) {

        //开始时间
        long startTime = System.currentTimeMillis();

        //类名
        String className = proceedingJoinPoint.getSignature().getDeclaringTypeName();

        //方法名
        String methodName = proceedingJoinPoint.getSignature().getName();

        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();

        //参数
        Object[] objects = proceedingJoinPoint.getArgs();

        //获得入参
        BaseEntity base = (BaseEntity) objects[0];

        Object object = null;

        //获取请求的request
        HttpServletRequest request = SpringContextUtils.getRequest();

        String token = request.getHeader(Const.HEAD_TOKEN);
//        String adminId = request.getHeader(Const.HEAD_TOKEN);

        //日志打印
        log.info("-----日志开始 [当前时间:{},当前访问ip:{},调用服务:{}.{} 的入参为:{}]-----",
                DateUtil.getCurrentDate(), request.getRequestURI(), className, methodName, JsonUtil.objectToJson(objects));

        try {
            //入参校验

            ApiOperation annotation = AnnotationUtils.findAnnotation(methodSignature.getMethod(), ApiOperation.class);

            //用户token校验 登录接口过滤
            if (!StringUtils.equals(methodName,"")) {
            }

            if (StringUtils.isNotBlank(token)) {
                String id = redisUtil.get(token);
                if ("null".equals(id)) {
                    throw new BaseException("201", "请重新登陆");
                }
                if (StringUtils.isNotBlank(id)) {
                    if (id.contains("web")) {
                        String adminId = id.replace("web", "");
                        if (StringUtils.isBlank(adminId) || "null".equals(adminId)) {
                            throw new BaseException("201", "请重新登陆");
                        }
                        base.setAdminId(Integer.parseInt(adminId));
                        //操作日志
                        if (StringUtils.equals("updateSysRoom", methodName)
                                || StringUtils.equals("addSysRoom", methodName)
                                || StringUtils.equals("addSysRoomDistrict", methodName)
                                || StringUtils.equals("updateSysRoomDistrict", methodName)) {
                        } else {
                            addLog(id, methodName, annotation.value(), JsonUtil.objectToJson(base));
                        }

                    } else if (id.contains("app")) {
                        String adminId = id.replace("app", "");
                        if (StringUtils.isBlank(adminId) || "null".equals(adminId)) {
                            throw new BaseException("201", "请重新登陆");
                        }
                        if (StringUtils.isNotBlank(adminId)) {
                            base.setUserId(Integer.parseInt(adminId));
                            //操作日志
                            addLog(id, methodName, annotation.value(), JsonUtil.objectToJson(base));
                        }
                    }
                }
            }
//            else if (!"login".equals(methodName)) {
//                throw new BaseException("201", "请重新登陆");
//            }
//            if (!StringUtils.equals(token, base.getToken())) {
//                //                throw new BaseException("250", "请重新登录");
//                //            }isUtil.hget(base.getTenantId(), base.getUserId());
//            }

            //执行目标接口
            object = proceedingJoinPoint.proceed();

        } catch (Throwable throwable) {
            //结束时间
            throwable.printStackTrace();
            log.error(throwable.getMessage());
            if (throwable instanceof BaseException) {
                BaseException e = (BaseException) throwable;
                if ("3050".equals(e.getCode())) {
                    object = RestResp.error(e.getCode(), "房间网关离线");
                } else {
                    object = RestResp.error(e.getCode(), e.getMessage());
                }
            } else {
                //创建新异常
                BaseException e = new BaseException("101", "系统繁忙");
                object = RestResp.error(e.getCode(), e.getMessage());
            }
        } finally {
            //结束时间
            long endTime = System.currentTimeMillis();

            log.info("-----日志结束 [当前时间:{}, 调用服务:{}.{}的出参为:{} 处理总时间:{}ms]-----",
                    DateUtil.getCurrentDate(), className, methodName, JsonUtil.objectToJson(object), (endTime - startTime));
        }
        return object;
    }

    private void addLog(String id,String method,String name,String param) {
      /*  SysLog sysLog = new SysLog();
        sysLog.setCreTime(LocalDateTime.now());
        sysLog.setParam(param);
        sysLog.setMethod(method);
        sysLog.setMethodName(name);
        if (id.contains("web")) {
            SysAdmin sysAdmin = sysAdminMapper.selectById(Integer.parseInt(id.replace("web", "")));
            sysLog.setId(Integer.parseInt(id.replace("web", "")));
            sysLog.setCreName(sysAdmin.getNickname());
        } else if (id.contains("app")){
            UserInfo sysAdmin = userInfoMapper.selectById(Integer.parseInt(id.replace("app", "")));
            sysLog.setCreUser(Integer.parseInt(id.replace("app", "")));
            sysLog.setCreName(sysAdmin.getUserName());
        }else {
            SysAdmin sysAdmin = sysAdminMapper.selectById(Integer.parseInt(id.replace("h5", "")));
            sysLog.setCreUser(Integer.parseInt(id.replace("h5", "")));
            sysLog.setCreName("h5"+ sysAdmin.getNickname());
        }*/
//        sysLogMapper.insert(sysLog);
    }


}